﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using Lync.Widget.Library.Presentation.Entities;
using Lync.Widget.Library.Presentation.Models;
using Lync.Widget.Library.Presentation.Views;

namespace Lync.Widget.Library.Presentation.Presenters
{
    public class GroupsPresenter : IGroupsPresenter
    {
        public IGroupsView View { get; set; }

        public IGroupsModel Model { get; set; }

        public GroupsPresenter(IGroupsView view, IGroupsModel model)
        {
            View = view;
            Model = model;
        }

        public void OnLoad()
        {

            try
            {
                View.ShowSearch = false;

                var groupConfig = Model.LoadConfiguration();

                if (groupConfig != null)
                {
                    if (String.IsNullOrEmpty(groupConfig.Root))
                    {
                        View.ErrorMessage = "Configuration doenst have a valid Active Directory root CN";
                        return;
                    }

                    View.OrganisationUnit = groupConfig.Root;
                    View.HuntgroupQuantity = groupConfig.HuntgroupQuantity;
                    View.TimeToWait = groupConfig.TimeToWait;
                    View.ShowDownloadButton = true;

                    Search(groupConfig.Groups);
                }
                else
                {
                    var adRoot = Model.GetActiveDirectoryRootFromConfiguration();

                    if (!String.IsNullOrEmpty(adRoot))
                    {
                        View.OrganisationUnit = adRoot;
                        Search();
                    }
                    else
                    {
                        View.ShowSearch = true;
                    }
                }
            }
            catch (Exception exception)
            {
                View.ErrorMessage = exception.Message;
            }
           
        }

        public void OnSave()
        {           
            var groups = View.SelectedGroups;

            try
            {
                if (groups.Count > 0)
                {
                    Model.SaveConfiguration(new GroupConfig
                                                {
                                                    Root = View.OrganisationUnit,
                                                    TimeToWait = View.TimeToWait,
                                                    HuntgroupQuantity = View.HuntgroupQuantity,
                                                    Groups = groups
                                                });
                    View.Saved = true;
                    View.ShowDownloadButton = true;
                }
            }
            catch (Exception exception)
            {
                View.ErrorMessage = exception.Message;
            }

        }

        public void OnDownload(HttpContext context)
        {
            var xml = Model.GetConfigurationXml();

            if (xml != null)
            {
                context.Response.Clear();
                context.Response.ContentType = "text/xml";
                context.Response.AddHeader("content-disposition", String.Format("attachment;filename={0}", "Adgroups.config"));
                context.Response.Buffer = true;
                xml.Save(context.Response.OutputStream);
                context.Response.End();
            }
        }

        public void Search(IList<IGroup> currentGroups = null)
        {
            View.ShowResults = false;
            View.ErrorMessage = null;

            var organisationUnit = View.OrganisationUnit;

            if (!string.IsNullOrEmpty(organisationUnit))
            {
                try
                {
                    var groups = Model.GetGroupsAndMembers(organisationUnit);

                    if (groups != null && groups.Count > 0)
                    {
                        View.Groups = PopulateValues(currentGroups, groups);
                        View.ShowResults = true;
                        View.ShowSaveButton = true;
                    }
                    else
                    {
                        View.ErrorMessage = "No groups found";
                    }
                }
                catch (Exception exception)
                {
                    View.ErrorMessage = exception.Message;
                }
            }
        }

        private IList<IGroup> PopulateValues(IList<IGroup> currentGroups, IList<IGroup> groups)
        {
            if (groups == null) return null;

            if (currentGroups == null) return groups;

            foreach (var group in groups)
            {
                var groupMatch = currentGroups.SingleOrDefault(g => g.DistinguishedName == group.DistinguishedName);

                if (groupMatch != null)
                {                    
                    group.Selected = true;
                    group.Id = groupMatch.Id;
                    group.HuntGroupSettings = new HuntGroupSetting
                                                  {
                                                      TimeToWait = groupMatch.HuntGroupSettings.TimeToWait,
                                                      UserCount = groupMatch.HuntGroupSettings.UserCount,
                                                  };

                    if (group.Members != null)
                    {
                        foreach (var member in group.Members)
                        {
                            var memberMatch = groupMatch.Members.SingleOrDefault(m => m.Sip == member.Sip);

                            if (memberMatch != null)
                            {
                                member.Priority = memberMatch.Priority;
                                member.Selected = true;
                            }
                        }
                    }
                }

                if (group.Members != null)
                {
                    foreach (var member in group.Members)
                    {
                        if (member.Priority == 0)
                        {
                            member.Priority = group.Members.ToList().Max(m => m.Priority) + 1;
                        }
                    }

                    group.Members = group.Members.OrderBy(m => m.Priority).ToList();
                }
            }

            return groups;
        }
    }
}